module.exports = core;
const path = require("path");
const pkg = require("../package.json");
const log = require("@hcnhistudy/log");
const exec = require("@hcnhistudy/exec")
const semver = require("semver");
const userHome = require("user-home");
const pathExists = require("path-exists").sync;
const { Command } = require("commander");
const colors = require("colors");
const { LOWERS_NODE_VERSION, DEFAULT_CLI_HOME } = require("./const");
let config;
// 实例化脚手架对象
const program = new Command();
function core() {
  // TODO
  try {
    checkPkgVersion();
    checkNodeVersoin();
    checkRoot();
    checkUserHome();
    // checkInputArgs();
    checkEnv();
    checkGlobalUpdata();
    registerCommand();
  } catch (e) {
    log.error(e.message);
  }
}

function checkNodeVersoin() {
  const currentVersion = process.version; // 获取当前node 版本号
  const lowerstVersion = LOWERS_NODE_VERSION;
  if (!semver.gte(currentVersion, lowerstVersion)) {
    throw new Error(
      colors.red(`node 版本太低需要安装 ${LOWERS_NODE_VERSION} 以上的nodejs`)
    );
  }
}

function checkPkgVersion() {
  // log.success("test", "sucss.........");
}

function checkRoot() {
  const rootCheck = require("root-check");
  rootCheck();
}
// // 4.检查用户主目录
function checkUserHome() {
  // console.log(userHome);
  if (!userHome || !pathExists(userHome)) {
    // 路径不存在
    throw new Error(colors.red(`当前登录用户主目录不存在`));
  }
}

// 5.检查入参
function checkInputArgs() {
  const argv = require("minimist")(process.argv.slice(2));
  if (argv.debug) {
    process.env.LOG_LEVEL = "verbose";
    // console.log("dddddddddddddd", log);
    log.verbose("debugger");
  } else {
    process.env.LOG_LEVEL = "info";
  }
}

// 6.获取环境变量，设置环境变量

function checkEnv() {
  const dotenv = require("dotenv");
  // const dotenvPath = path.relative(userHome, ".env");
  const dotenvPath = path.resolve(userHome, ".env");
  if (pathExists(dotenvPath)) {
    config = dotenv.config({
      path: dotenvPath,
    });
  }
  createDefaultConfig();
}
// 创建环境变量
function createDefaultConfig() {
  const cliConfig = {
    home: userHome,
  };
  // 这个环境变量存在
  if (process.env.CLI_HOME) {
    cliConfig["cliHome"] = path.join(userHome, process.env.CLI_HOME);
  } else {
    // 不存在，就设置这个环境变量
    cliConfig["cliHome"] = path.join(userHome, DEFAULT_CLI_HOME);
  }

  // 把最终生成的，赋值给环境变量
  process.env.CLI_HOME_PATH = cliConfig["cliHome"];
  // console.log(process.env.CLI_HOME_PATH);
}
// 7 检查脚手架是否要更新

async function checkGlobalUpdata() {
  // 1.当前版本号和模块名
  const currentVersion = pkg.version;
  const npmName = pkg.name;
  const { getSemverVersion } = require("@hcnhistudy/get-npm-info");
  const lastVersion = await getSemverVersion(currentVersion, npmName);
  if (lastVersion) {
    log.warn(
      "更新提醒",
      colors.yellow(
        `请手动更新 ${npmName}, 当前的版本是 ${currentVersion}，最新版本：${lastVersion}，执行 npm install -g ${npmName}`
      )
    );
  } else {
    // log.error("检查脚手架是否要更新 失败");
  }
}

// 8 命令注册
function registerCommand() {
  program
    .name(Object.keys(pkg.bin)[0])
    .usage("<command> [options]")
    .version(pkg.version)
    .option("-d --debug", "是否开启调试模式", false)
    .option("-tp --targetPath <targetPath>", "是否指定本地调试文件路径", "");
  program
    .command("init [projectName]")
    .option("-f, --force", "是否强制初始化项目")
    .action(exec); // name option parentOptions
  program.on("option:debug", () => {
    const options = program.opts();
    if (options.debug) {
      process.env.LOG_LEVEL = "verbose"; // 修改日志级别
    } else {
      process.env.LOG_LEVEL = "info";
    }
    log.level = process.env.LOG_LEVEL; // 设置日志级别
  });
  program.on("option:targetPath", () => {
    const options = program.opts();
    if (options.targetPath) {
      process.env.CLI_TARGET_PATH = options.targetPath;
    }
  });
  program.on("command:*", (obj) => {
    if (Array.isArray(obj) && obj.length > 0) {
      console.log(colors.red(`未知的命令：${obj.join(",")}`));
      const availableCommands = program.commands.map((cmd) => cmd.name());
      if (availableCommands.length > 0) {
        console.log(colors.red(`可用的命令：${vaailableCommands.join(",")}`));
      }
    }
  });
  if (process.argv.length < 3) {
    program.outputHelp();
  }
  program.parse(process.argv);
}
